home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Cafe 3
/
Visual Cafe 3.ISO
/
Vcafe
/
JFC.bin
/
MacComboBoxUI.java
< prev
next >
Wrap
Text File
|
1998-06-30
|
19KB
|
730 lines
/*
* @(#)MacComboBoxUI.java 1.6 98/02/02
*
* Copyright (c) 1998 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.plaf.mac;
import java.awt.*;
import java.awt.event.*;
import java.io.Serializable;
import com.sun.java.swing.*;
import com.sun.java.swing.plaf.*;
import com.sun.java.swing.border.*;
/**
* ComboBox mac look and feel
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version @(#)MacComboBoxUI.java 1.0 01/20/98
* @author Symantec
*/
public class MacComboBoxUI extends ComboBoxUI implements Serializable
{
static Color pressedBackground = UIManager.getColor("Control.pressedBackground");
static Color pressedForeground = UIManager.getColor("Control.pressedForeground");
static Color disabledBackground = UIManager.getColor("Control.disabledBackground");
static Color disabledForeground = UIManager.getColor("Control.disabledForeground");
static Color enabledBackground = UIManager.getColor("MenuItem.background");
static Dimension defaultSize = new Dimension(100, 20);
protected JComboBox comboBox = null;
protected CellRendererPane currentValuePane = new CellRendererPane();
protected JButton arrowButton;
protected Component editor;
protected JPopupMenu menu = null;
protected JList listBox = null;
protected ActionListener actionListener = new ComboBoxMenuItemListener();
protected MouseListener mouseListener = new ComboBoxMouseListener();
protected ItemListener itemListener = new ComboBoxItemListener();
/*
*
* ComponentUI methods
*
*/
public static ComponentUI createUI(JComponent c) {
return new MacComboBoxUI();
}
public void installUI(JComponent c) {
comboBox = (JComboBox) c;
arrowButton = new JButton(MacMenuUtilities.getComboBoxPopupArrowIcon()) {
{
setModel(new ComboBoxButtonModel());
setMargin(new Insets(2, 2, 2, 2/*1, 3*/));
setRequestFocusEnabled(false);
}
};
arrowButton.addMouseListener(mouseListener);
comboBox.add(arrowButton);
comboBox.add(currentValuePane);
comboBox.setLayout(new ComboBoxLayout());
comboBox.addItemListener(itemListener);
comboBox.addMouseListener(mouseListener);
if (comboBox.getRenderer() == null)
comboBox.setRenderer((ListCellRenderer)(UIManager.get("ComboBox.renderer")));
LookAndFeel.installColorsAndFont(comboBox,"ComboBox.background","ComboBox.foreground",
"ComboBox.font");
editablePropertyChanged();
c.setRequestFocusEnabled(false);
}
public void uninstallUI(JComponent c) {
hidePopup();
removeEditor();
if (arrowButton != null) {
comboBox.remove(arrowButton);
arrowButton.removeMouseListener(mouseListener);
arrowButton = null;
}
comboBox.setLayout(null);
comboBox.removeItemListener(itemListener);
comboBox.removeMouseListener(mouseListener);
comboBox.remove(currentValuePane);
if (comboBox.getRenderer() instanceof UIResource)
comboBox.setRenderer(null);
if (comboBox.getEditor() instanceof UIResource)
comboBox.setEditor(null);
if (comboBox.getBorder() instanceof UIResource)
comboBox.setBorder(null);
comboBox = null;
}
public void paint(Graphics g, JComponent c) {
if (!comboBox.isEditable()) {
Rectangle bounds = rectangleForCurrentValue();
Color t = g.getColor();
Color bgColor;
Color fgColor;
if (popupIsVisible()) {
bgColor = pressedBackground;
fgColor = pressedForeground;
}
else if (c.isEnabled()) {
bgColor = enabledBackground;
fgColor = comboBox.getForeground();
}
else {
bgColor = disabledBackground;
fgColor = disabledForeground;
}
g.setColor(bgColor);
g.fillRect(bounds.x,bounds.y,bounds.width,bounds.height);
g.setColor(t);
ListCellRenderer renderer = comboBox.getRenderer();
validateList();
listBox.setFont(comboBox.getFont());
listBox.setForeground(fgColor);
listBox.setBackground(bgColor);
Component rendererComponent = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false);
// Just in case!
rendererComponent.setFont(comboBox.getFont());
rendererComponent.setForeground(fgColor);
rendererComponent.setBackground(bgColor);
currentValuePane.paintComponent(g, rendererComponent, comboBox, bounds);
}
}
public Dimension getPreferredSize(JComponent c) {
validateList();
Dimension preferredSize = new Dimension();
Dimension testSize;
ListCellRenderer renderer = comboBox.getRenderer();
ComboBoxModel model = comboBox.getModel();
if (renderer != null && model.getSize() > 0) {
for (int i = 0, numElements = model.getSize(); i < numElements; i++) {
Component cpn = renderer.getListCellRendererComponent(listBox, model.getElementAt(i), -1, false, false);
currentValuePane.add(cpn);
cpn.setFont(comboBox.getFont());
testSize = cpn.getPreferredSize();
currentValuePane.remove(cpn);
preferredSize.width = Math.max(preferredSize.width, testSize.width);
preferredSize.height = Math.max(preferredSize.height, testSize.height);
}
if (comboBox.isEditable()) {
testSize = editor.getPreferredSize();
preferredSize.width = Math.max(preferredSize.width, testSize.width);
preferredSize.height = Math.max(preferredSize.height, testSize.height);
}
} else {
preferredSize.width = defaultSize.width;
preferredSize.height = defaultSize.height;
}
if (arrowButton != null) {
testSize = arrowButton.getPreferredSize();
preferredSize.width += testSize.width;
preferredSize.height = Math.max(preferredSize.height, testSize.height);
}
return preferredSize;
}
public Dimension getMinimumSize(JComponent c) {
validateList();
Dimension minimumSize = new Dimension();
Dimension testSize;
ListCellRenderer renderer = comboBox.getRenderer();
ComboBoxModel model = comboBox.getModel();
if (renderer != null && model.getSize() > 0) {
for (int i = 0, numElements = model.getSize(); i < numElements; i++) {
Component cpn = renderer.getListCellRendererComponent(listBox, model.getElementAt(i), -1, false, false);
currentValuePane.add(cpn);
cpn.setFont(comboBox.getFont());
testSize = cpn.getMinimumSize();
currentValuePane.remove(cpn);
minimumSize.width = Math.max(minimumSize.width, testSize.width);
minimumSize.height = Math.max(minimumSize.height, testSize.height);
}
if (comboBox.isEditable()) {
testSize = editor.getMinimumSize();
minimumSize.width = Math.max(minimumSize.width, testSize.width);
minimumSize.height = Math.max(minimumSize.height, testSize.height);
}
} else {
minimumSize.width = defaultSize.width;
minimumSize.height = defaultSize.height;
}
if (arrowButton != null) {
testSize = arrowButton.getMinimumSize();
minimumSize.width += testSize.width;
minimumSize.height = Math.max(minimumSize.height, testSize.height);
}
return minimumSize;
}
public Dimension getMaximumSize(JComponent c) {
validateList();
Dimension maximumSize = new Dimension();
Dimension testSize;
ListCellRenderer renderer = comboBox.getRenderer();
ComboBoxModel model = comboBox.getModel();
if (renderer != null && model.getSize() > 0) {
for (int i = 0, numElements = model.getSize(); i < numElements; i++) {
Component cpn = renderer.getListCellRendererComponent(listBox, model.getElementAt(i), -1, false, false);
currentValuePane.add(cpn);
cpn.setFont(comboBox.getFont());
testSize = cpn.getMinimumSize();
currentValuePane.remove(cpn);
maximumSize.height = Math.max(maximumSize.height, testSize.height);
}
if (comboBox.isEditable()) {
testSize = editor.getMaximumSize();
maximumSize.height = Math.max(maximumSize.height, testSize.height);
}
} else {
maximumSize.height = defaultSize.height;
}
if (arrowButton != null) {
testSize = arrowButton.getMaximumSize();
maximumSize.height = Math.max(maximumSize.height, testSize.height);
}
maximumSize.width = Short.MAX_VALUE;
return maximumSize;
}
/*
*
* ComboBoxUI methods
*
*/
/** This method is called when the maximum number of rows is changing **/
public void maximumRowCountChanged() {
if (popupIsVisible()) {
hidePopup();
showPopup();
}
}
/** This method is called when the editable property changes. **/
public void editablePropertyChanged() {
if (comboBox.isEditable())
addEditor();
else
removeEditor();
}
/** This method is called when the enabled property changes **/
public void enablePropertyChanged() {
if (comboBox.isEnabled()) {
if (editor != null)
editor.setEnabled(true);
if (arrowButton != null)
arrowButton.setEnabled(true);
} else {
if (editor != null)
editor.setEnabled(false);
if (arrowButton != null)
arrowButton.setEnabled(false);
}
comboBox.repaint();
}
/** This method request the UI to show the popup **/
public void showPopup() {
validateMenu();
validateList();
Point menuPt;
if (comboBox.isEditable() && arrowButton != null) {
menuPt = arrowButton.getLocation();
} else {
menuPt = new Point(0, 0);
}
int selectedIndex = comboBox.getSelectedIndex();
menu.show(comboBox,menuPt.x, menuPt.y);
menu.requestFocus();
comboBox.repaint();
MenuElement me[];
if (selectedIndex >= 0) {
me = new MenuElement[2];
me[1] = (MenuElement) menu.getComponentAtIndex(selectedIndex);
} else {
me = new MenuElement[1];
}
me[0] = menu;
MenuSelectionManager.defaultManager().setSelectedPath(me);
}
/** This method request the UI to hide the popup **/
public void hidePopup() {
if (!popupIsVisible())
return;
menu.setVisible(false);
comboBox.repaint();
if (comboBox.isEditable())
editor.requestFocus();
resetMenu();
}
/** This method determines if the popup is visible **/
public boolean popupIsVisible() {
if (menu == null)
return false;
else
return menu.isVisible();
}
/** This method determines whether or not the combo box itself is traversable **/
public boolean isFocusTraversable() {
return false;
}
/**
* This method asks the UI for the JList is using to display the
* contents of the ComboBox. The return value is meant to be used
* for read-only values -- any modification to the JList is
* unsupported.
*/
public JList getList() {
return listBox;
}
void addEditor() {
if (comboBox.getBorder() instanceof UIResource)
comboBox.setBorder(null);
if (arrowButton != null)
arrowButton.setBorder(MacBorderFactory.getEditableComboBoxArrowBorder());
if (editor != null) {
comboBox.remove(editor);
editor = null;
}
if (comboBox.getEditor() == null)
comboBox.setEditor((ComboBoxEditor) (UIManager.get("ComboBox.editor")));
editor = comboBox.getEditor().getEditorComponent();
comboBox.add(editor);
editor.setFont(comboBox.getFont());
comboBox.configureEditor(comboBox.getEditor(),comboBox.getSelectedItem());
}
void removeEditor() {
if (editor != null) {
comboBox.remove(editor);
editor = null;
}
if (comboBox.getBorder() == null || comboBox.getBorder() instanceof UIResource)
comboBox.setBorder(MacBorderFactory.getComboBoxBorder());
if (arrowButton != null)
arrowButton.setBorder(MacBorderFactory.getComboBoxArrowBorder());
}
Rectangle rectangleForCurrentValue() {
Dimension cbSize = comboBox.getSize();
Insets insets = comboBox.getInsets();
Rectangle r = new Rectangle(insets.left, insets.top, cbSize.width - insets.left, cbSize.height - (insets.top + insets.bottom));
if (arrowButton != null)
r.width -= arrowButton.getSize().width;
else
r.width -= insets.right;
return r;
}
void validateMenu() {
if (menu == null) {
// Create the popup menu and populate it with items
menu = new JPopupMenu();
menu.addPopupMenuListener(new ComboBoxRepaintRequester());
menu.setDoubleBuffered(true);
menu.setInvoker(comboBox);
} else {
resetMenu();
}
int numItems = comboBox.getModel().getSize();
for (int anItem = 0; anItem < numItems; anItem++) {
JMenuItem mi = menu.add(new ComboBoxMenuItem(anItem));
mi.addActionListener(actionListener);
}
}
// Combo box implementations expect a listBox, so we need to create one
void validateList() {
if (listBox == null) {
listBox = new JList(comboBox.getModel());
listBox.setCellRenderer(comboBox.getRenderer());
}
}
void resetMenu() {
MenuSelectionManager.defaultManager().clearSelectedPath();
Component[] components = menu.getComponents();
int numItems = components.length;
if (numItems > 0) {
for (int anItem = 0; anItem < numItems; anItem++) {
JMenuItem mi = (JMenuItem) components[anItem];
mi.removeActionListener(actionListener);
}
menu.removeAll();
}
}
/*
*
* MouseListener methods
*
*/
class ComboBoxMouseListener extends MouseAdapter {
/**
* Invoked when a mouse button has been pressed on a component.
*/
public void mousePressed(MouseEvent e) {
if (!comboBox.isEnabled())
return;
if (popupIsVisible()) {
hidePopup();
} else {
showPopup();
}
}
/**
* Invoked when a mouse button has been released on a component.
*/
public void mouseReleased(MouseEvent e) {
if (popupIsVisible())
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
/**
* Invoked when the mouse enters a component.
*/
public void mouseEntered(MouseEvent e) {
if (popupIsVisible())
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
/**
* Invoked when the mouse exits a component.
*/
public void mouseExited(MouseEvent e) {
if (popupIsVisible())
MenuSelectionManager.defaultManager().processMouseEvent(e);
}
}
/*
*
* MouseListener methods
*
*/
class ComboBoxItemListener implements ItemListener {
/**
* Invoked when an item's state has been changed.
*/
public void itemStateChanged(ItemEvent e) {
Object v = comboBox.getModel().getSelectedItem();
if(editor != null) {
comboBox.configureEditor(comboBox.getEditor(),v);
} else {
comboBox.repaint(rectangleForCurrentValue());
}
}
}
/*
*
* MouseListener methods
*
*/
class ComboBoxMenuItemListener implements ActionListener {
/**
* Invoked when a menu item is selected.
*/
public void actionPerformed(ActionEvent e) {
comboBox.setSelectedIndex(((ComboBoxMenuItem) e.getSource()).getItemIndex());
}
}
/*
*
* LayoutManager methods
*
*/
class ComboBoxLayout implements LayoutManager {
/**
* Adds the specified component with the specified name to
* the layout.
* @param name the component name
* @param comp the component to be added
*/
public void addLayoutComponent(String name, Component comp) {}
/**
* Removes the specified component from the layout.
* @param comp the component ot be removed
*/
public void removeLayoutComponent(Component comp) {}
/**
* Calculates the preferred size dimensions for the specified
* panel given the components in the specified parent container.
* @param parent the component to be laid out
*
* @see #minimumLayoutSize
*/
public Dimension preferredLayoutSize(Container parent) {
return ((JComboBox)parent).getPreferredSize();
}
/**
* Calculates the minimum size dimensions for the specified
* panel given the components in the specified parent container.
* @param parent the component to be laid out
* @see #preferredLayoutSize
*/
public Dimension minimumLayoutSize(Container parent) {
return ((JComboBox)parent).getMinimumSize();
}
/**
* Lays out the container in the specified panel.
* @param parent the component which needs to be laid out
*/
public void layoutContainer(Container parent) {
if (arrowButton != null) {
Dimension cbSize = comboBox.getSize();
Dimension arrowSize = arrowButton.getPreferredSize();
if (comboBox.isEditable()) {
arrowButton.setBounds(cbSize.width - arrowSize.width, (cbSize.height - arrowSize.height)/2, arrowSize.width, arrowSize.height);
} else {
arrowButton.setBounds(cbSize.width - arrowSize.width, 0, arrowSize.width, cbSize.height);
}
}
if (editor != null) {
editor.setBounds(rectangleForCurrentValue());
}
}
}
class ComboBoxMenuItem extends JMenuItem {
int itemIndex;
public ComboBoxMenuItem(int menuItem) {
super();
itemIndex = menuItem;
}
JComboBox getComboBox() {
return comboBox;
}
int getItemIndex() {
return itemIndex;
}
/**
* Returns the name of the L&F class that renders this component.
*
* @return "ComboBoxMenuItemUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
public String getUIClassID() {
return "ComboBoxMenuItemUI";
}
}
class ComboBoxRepaintRequester implements ActionListener, com.sun.java.swing.event.PopupMenuListener {
Timer timer = null;
ComboBoxRepaintRequester() {
}
/**
* This method is called before the popup menu becomes visible
*/
public void popupMenuWillBecomeVisible(com.sun.java.swing.event.PopupMenuEvent e) {}
/**
* This method is called before the popup menu becomes invisible
* Note that a JPopupMenu can become invisible any time
*/
public void popupMenuWillBecomeInvisible(com.sun.java.swing.event.PopupMenuEvent e) {
startTimer();
}
/**
* This method is called when the popup menu is canceled
*/
public void popupMenuCanceled(com.sun.java.swing.event.PopupMenuEvent e) {}
private void startTimer() {
timer = new Timer(200,this);
timer.start();
}
public void actionPerformed(ActionEvent e) {
if (timer != null) {
timer.stop();
timer = null;
}
comboBox.repaint();
}
}
class ComboBoxButtonModel extends DefaultButtonModel {
/**
* Checks if the button is armed.
*/
public boolean isArmed() {
return super.isArmed() || popupIsVisible();
}
/**
* Checks if the button is pressed.
*/
public boolean isPressed() {
return super.isPressed() || popupIsVisible();
}
}
}